using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Radiality;

namespace XnaExample {
	public class Game1 : Game {
		public GraphicsDeviceManager graphics { get; set; }
		public Label Label1 { get; set; }
		public Label Label2 { get; set; }

		readonly RadialityContainer container;

		public Game1() {
			container = new RadialityContainer();

			//Any game components are automatically added to the game Components collections
			container.InstanceCreated += ((sender, e) => {
				var component = e.instance as GameComponent;
				if (component != null) {
					Components.Add(component);
				}
			});

			InitializeContainer();
		}

		private void InitializeContainer() {
			//Add the game instance to the container so that it can be "injected"
			container.Bind<Game1>().To(
				r => {
					Content.RootDirectory = "Content";
					return this;
				});

			//Bind the GraphicsDeviceManager
			container.Bind<GraphicsDeviceManager>().To(r => new GraphicsDeviceManager(r.Get<Game1>()));

			//Create the labels, note that no external resources like the sprite batch or the font are specifically set,
			//they will be injected by the container
			container.Bind("Label1").To(r => new Label(r.Get<Game1>(), Color.White, new Vector2(100, 100), "Radiality:"));
			container.Bind("Label2").To(r => new Label(r.Get<Game1>(), Color.White, new Vector2(108, 125), "Pertaining to structures that radiate from a central point."));

			//the LoadContent "lifecycle" binding is used to load the resources at the right time - in LoadContent(), 
			//and since this happened after the objects were created the injection is requested with InjectNow.
			//This is used primarily to inject resources that need the GraphicsDeviceManager like the spriteBatch
			//and content stuff
			container.Bind("LoadContent").To(r => {
				r.Bind<GraphicsDevice>().To(c => r.Get<GraphicsDeviceManager>().GraphicsDevice).InjectNow();
				r.Bind<SpriteBatch>().To(c => new SpriteBatch(r.Get<GraphicsDeviceManager>().GraphicsDevice)).InjectNow();
				r.Bind<SpriteFont>().To(c => r.Get<Game1>().Content.Load<SpriteFont>("SpriteFont1")).InjectNow();
				return null;
			});

			container.Get<Game1>();
		}

		protected override void LoadContent() {
			container.Execute("LoadContent");
		}

		protected override void Update(GameTime gameTime) {
			if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
				Exit();
			base.Update(gameTime);
		}

		protected override void Draw(GameTime gameTime) {
			GraphicsDevice.Clear(Color.CornflowerBlue);
			base.Draw(gameTime);
		}
	}
}
